AddMinimapAtlas("images/mappin.xml")
local t_util = require "libs/tableutil"
local e_util = require "libs/entutil"
local c_util = require "libs/calcutil"
local i_util = require "libs/inpututil"
local allow_tele = GetModConfigData("sw_justgo") == "god" or e_util:IsHuxi()

local function MakePin()
    local inst = GLOBAL.CreateEntity()
    inst.entity:AddTransform()
    inst.entity:AddMiniMapEntity()
    inst.MiniMapEntity:SetIcon("mappin.tex")
    inst.MiniMapEntity:SetPriority(5)
    inst.MiniMapEntity:SetDrawOverFogOfWar(true)
    inst.MiniMapEntity:SetCanUseCache(false)
    inst.MiniMapEntity:SetEnabled(false)
    inst.entity:SetCanSleep(false)
    inst:AddTag("FX")
    inst:AddTag("NOBLOCK")
    inst:AddTag("NOCLICK")
    return inst
end

local mappin1 = MakePin()
local mappin2 = MakePin()
mappin1.MiniMapEntity:SetIsProxy(true)
mappin2.MiniMapEntity:SetIsProxy(false)

local function SetPin(pos)
    mappin1.Transform:SetPosition(pos:Get())
    mappin2.Transform:SetPosition(pos:Get())
    mappin1.MiniMapEntity:SetEnabled(true)
    mappin2.MiniMapEntity:SetEnabled(true)
end

local time_interval = 0.3
local time_last = 0
local pos_source, pos_target, pressed_ctrl
AddClassPostConstruct("screens/mapscreen", function(self)
    local _OnControl = self.OnControl
    self.OnControl = function(self, control, down, ...)
        if down and control == GLOBAL.CONTROL_SECONDARY then
            -- 适配全球定位和扫描地皮，不可删
            local mapbutton = t_util:GetChild(t_util:GetChild(t_util:GetChild(self, "br_root"), "br_scale_root"),
                                              "Map Controls")
            local pc = GLOBAL.ThePlayer and GLOBAL.ThePlayer.components.playercontroller
            if (mapbutton and mapbutton.focus) or (not pc) then
                return _OnControl(self, control, down, ...)
            end
            -- 右键地图有动作时，双击地图才能生效
            local now = GLOBAL.GetTime()
            pos_target = GLOBAL.Vector3(self:GetWorldPositionAtCursor())
            pos_source = GLOBAL.ThePlayer:GetPosition()
            local lmb, rmb = pc:GetMapActions(pos_target)
            if rmb and now - time_last < time_interval then
                -- TODO:玩家停止移动
                (require "libs/playerutil"):StopWalking()
                return _OnControl(self, control, down, ...)
            end
            time_last = now
            -- 替换右键
            if allow_tele then
                local fnstr =
                    "local h = ThePlayer and ThePlayer.Transform and ThePlayer.components.health if h and h:IsInvincible() then ThePlayer.Transform:SetPosition(" ..
                        pos_target.x .. ", 0, " .. pos_target.z .. ") end"
                i_util:ExRemote(fnstr)
            end
            SetPin(pos_target)
            if pc.locomotor then
                pc:DoAction(GLOBAL.BufferedAction(GLOBAL.ThePlayer, nil, GLOBAL.ACTIONS.WALKTO, nil, pos_target))
            else
                local dirx, diry = c_util:GetDirection(pos_source, pos_target, "up")
                GLOBAL.SendRPCToServer(GLOBAL.RPC.DirectWalking, dirx, diry)
            end
            pressed_ctrl = false
        else
            return _OnControl(self, control, down, ...)
        end
    end
end)

AddPlayerActivatedFunc(function(player, world)
    local p_util = require "libs/playerutil"
    player:ListenForEvent("breakctrl_withhx", function()
        pressed_ctrl = true
    end)
    player:ListenForEvent("position_withhx", function(player, pos)
        if not pressed_ctrl and pos_source and pos_target then
            if c_util:GetDistWithoutSqrt(pos_source.x, pos_source.z, pos.x, pos.z) >
                c_util:GetDistWithoutSqrt(pos_source.x, pos_source.z, pos_target.x, pos_target.z) - 2 then
                p_util:StopWalking()
            end
        end
    end)
end)
